package test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.swing.text.ChangedCharSetException;
import javax.swing.text.EditorKit;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;

public class DownloadURL
{
	public static final SimpleDateFormat sdfDBCurrentDate = new SimpleDateFormat("yyyyMMdd");
	static String globalPathPrefix = "";
	static SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();

	public static void main(final String[] args) throws Exception
	{
		final SSLContext ctx = SSLContext.getInstance("TLS");
		ctx.init(new KeyManager[0], new TrustManager[] { new DefaultTrustManager() }, new SecureRandom());
		SSLContext.setDefault(ctx);
		if (args.length == 0)
		{
			System.out.println("Usage: java DownloadURL <-latest | -latest30 | YYYYMMDD>");
			System.out.println("e.g.	 java DownloadURL 20101112");
			return;
		}
		if (args[0].equals("-latest"))
		{
			final Calendar ca1 = Calendar.getInstance();
			for (int i = 0; i < 3; i++)
			{
				final String strDate = sdfDBCurrentDate.format(ca1.getTime());
				System.out.println("Date: " + strDate);
				listURL("https://10.240.149.11:9443/LOGS/indLogs/prod/archive/", strDate);
				ca1.add(Calendar.DATE, -1);
			}
			listURL("https://10.240.149.11:9443/LOGS/indLogs/prod/", "");
			return;
		}

		if (args[0].equals("-latest30"))
		{
			final Calendar ca1 = Calendar.getInstance();
			ca1.set(2010, 10 - 1, 1);
			for (int i = 0; i < 31; i++)
			{
				final String strDate = sdfDBCurrentDate.format(ca1.getTime());
				System.out.println("Date: " + strDate);
				listURL("https://10.240.149.11:9443/LOGS/indLogs/prod/archive/", strDate);
				ca1.add(Calendar.DATE, -1);
			}
			listURL("https://10.240.149.11:9443/LOGS/indLogs/prod/", "");
			return;
		}
		// downloadURL("https://google.hu");
		// downloadURL("http://download.sysinternals.com/Files/AdRestore.zip");

		// downloadURL(strURLPrefix + "sts.log.gz");
		// downloadURL(strURLPrefix +"wf.cc.log.gz");
		// downloadURL(strURLPrefix + "wf.co.log.gz");
		// downloadURL(strURLPrefix + "wf.ib.log.gz");

		// downloadZUNODay("");
		// downloadZUNODay("20101110"); //Not usable
		//listURL("https://10.240.149.11:9443/LOGS/indLogs/prod/",null);
		//listURL("https://10.240.149.11:9443/LOGS/indLogs/prod/archive/", "20101111");

		for (int i = 0; i < args.length; i++)
		{
			listURL("https://10.240.149.11:9443/LOGS/indLogs/prod/archive/", args[i]);
		}

		System.err.println("END.");
	}

	//Generating URL usable only for current logs, not good for archive days
	public static void downloadZUNODay(final String dayPrefix) throws Exception
	{
		String strURLPrefix = "https://10.240.149.11:9443/LOGS/indLogs/prod/";
		globalPathPrefix = dayPrefix;
		if (!dayPrefix.equals(""))
			strURLPrefix = strURLPrefix + "archive/" + dayPrefix + "/";

		final String[] XY = { "x", "y" };
		final int maxInstance = 2;
		final int maxNode = 3;
		final String[] strlogs = { "admin", "jmschannel", "sts", "sts.perfstat", "wf.cc", "wf.co", "wf.ib", "wf.ib.perfstat" };

		for (int iXY = 0; iXY < XY.length; iXY++)
		{
			for (int i = 1; i <= maxInstance; i++)
			{
				for (int j = 1; j <= maxNode; j++)
				{
					for (int iLogs = 0; iLogs < strlogs.length; iLogs++)
					{
						final String strURL = strURLPrefix + XY[iXY] + "indsk" + i + "_" + j + "." + strlogs[iLogs] + ".log.gz";
						System.out.println(strURL);
						try
						{
							downloadURL(strURL);
						}
						catch (final java.io.FileNotFoundException e)
						{
							System.err.println(strURL + " not found");
						}
					}
				}
			}
		}
	}

	public static void downloadURL(final String strUrl) throws Exception
	{
		final URL url = new URL(strUrl);

		HttpURLConnection conn;
		if (url.getProtocol().equals("https"))
		{
			final HttpsURLConnection sslconn = (HttpsURLConnection) url.openConnection();
			// sslconn.setSSLSocketFactory(sslsocketfactory);
			sslconn.setHostnameVerifier(new NullHostnameVerifier());
			conn = sslconn;
		}
		else
		{
			conn = (HttpURLConnection) url.openConnection();
		}
		final InputStream inputstream = conn.getInputStream();
		// BufferedReader bufferedreader = new BufferedReader(new
		// InputStreamReader(inputstream));
		final BufferedInputStream bif = new BufferedInputStream(inputstream);

		final String outFileName = getNameFromPath(url.getPath());
		if (!globalPathPrefix.equals(""))
		{
			final boolean success = (new File(globalPathPrefix)).mkdir();
			if (success)
			{
				System.out.println("Directory: " + globalPathPrefix + " created");
			}
		}
		final File outFile = new File(globalPathPrefix + "/" + (!outFileName.equals("") ? (outFileName) : "index.html"));
		final BufferedOutputStream fout = new BufferedOutputStream(new FileOutputStream(outFile));

		copyStream(bif, fout);
		fout.close();

	}

	public static void listURL(String strUrl, final String strDirectory) throws Exception
	{
		if (!strDirectory.equals(""))
			strUrl += strDirectory;
		final URL url = new URL(strUrl);
		System.err.println("listing and downloading URL " + strUrl + " to " + strDirectory);
		HttpURLConnection conn;
		if (url.getProtocol().equals("https"))
		{
			final HttpsURLConnection sslconn = (HttpsURLConnection) url.openConnection();
			// sslconn.setSSLSocketFactory(sslsocketfactory);
			sslconn.setHostnameVerifier(new NullHostnameVerifier());
			conn = sslconn;
		}
		else
		{
			conn = (HttpURLConnection) url.openConnection();
		}
		//		InputStream inputstream = conn.getInputStream();
		//		BufferedReader br = new BufferedReader(new InputStreamReader(
		//				inputstream));
		//		while ((thisLine = br.readLine()) != null) {
		//			System.out.println(thisLine);
		//		}

		try
		{

			final Reader reader = new InputStreamReader(conn.getInputStream());
			final EditorKit kit = new HTMLEditorKit();
			final HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument();
			doc.putProperty("IgnoreCharsetDirective", new Boolean(true));
			kit.read(reader, doc, 0);
			final HTMLDocument.Iterator it = doc.getIterator(HTML.Tag.A);
			while (it.isValid())
			{
				final SimpleAttributeSet s = (SimpleAttributeSet) it.getAttributes();
				final String href = (String) s.getAttribute(HTML.Attribute.HREF);
				if (!href.startsWith("?") && !href.endsWith("/"))
				{
					System.out.println(href);
					if (strDirectory.equals(""))
						globalPathPrefix = "TODAY_TMP";
					else
						globalPathPrefix = strDirectory;
					downloadURL(strUrl + "/" + href);
				}
				it.next();
			}
		}
		catch (final ChangedCharSetException e)
		{
			System.out.println(e.getCharSetSpec());
		}

	}

	public static String getNameFromPath(final String path)
	{
		int i = 0;
		for (i = path.length(); i > 0;)
		{
			final char c = path.charAt(--i);
			if (c == '/' || c == '\\')
			{
				i++;
				break;
			}
		}
		return path.substring(i, path.length());

	}

	public static void copyStream(final InputStream in, final OutputStream out) throws IOException
	{

		final BufferedInputStream bin = new BufferedInputStream(in);
		final BufferedOutputStream bout = new BufferedOutputStream(out);

		while (true)
		{
			final int datum = bin.read();
			if (datum == -1)
				break;
			bout.write(datum);
		}
		bout.flush();
	}

	private static class NullHostnameVerifier implements HostnameVerifier
	{
		public boolean verify(final String hostname, final SSLSession session)
		{
			return true;
		}
	}

	private static class DefaultTrustManager implements X509TrustManager
	{
		@Override
		public void checkClientTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException
		{
		}

		@Override
		public void checkServerTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException
		{
		}

		@Override
		public X509Certificate[] getAcceptedIssuers()
		{
			return null;
		}
	}
}